/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Tools;

import GUI.MainWindow;
import GUI.TableTaskManager;
import HTTPDownloader.HTTPTaskManager;
import HTTPDownloader.Status;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTable;
import org.apache.commons.io.filefilter.SuffixFileFilter;

/**
 *
 * @author Lone_Wolf
 */
public class AppDataManager {
    
    private TableTaskManager tableTaskManager = null;
    private JTable table_tasks = null;
    private MainWindow mainWindow = null;
    private FileTools fileTools = new FileTools();
    private File MainDir;
    private File TorrentsDir;
    private File TasksDir;
    private File TasksFile;
    private File SettingsFile;
    private File HistoryDir;
    
    public AppDataManager() {
        
        System.out.println(fileTools.getOSName());
        System.out.println(fileTools.getOSVersion());
        //Windows
        if ("Windows 7".equals(fileTools.getOSName())) {
            MainDir = new File(fileTools.formatPath(fileTools.getUserDir() + "\\AppData\\Local\\Scitner"));
        } else if ("Windows NT (unknown)".equals(fileTools.getOSName())) {
            if ("6.2".equals(fileTools.getOSVersion())) {
                MainDir = new File(fileTools.formatPath(fileTools.getUserDir() + "\\AppData\\Local\\Scitner"));
            }
        }
        setUpFiles();
    }
    
    public void setMainWindow(MainWindow mainWindow) {
        this.mainWindow = mainWindow;
        this.tableTaskManager = this.mainWindow.getTableTaskManager();
        this.table_tasks = this.mainWindow.getTableTasks();
    }
    
    public void setUpFiles() {
        try {
            // Directories
            MainDir.mkdirs();
            TorrentsDir = new File(fileTools.formatPath(MainDir.getAbsolutePath() + "\\Torrents"));
            TorrentsDir.mkdirs();
            HistoryDir = new File(fileTools.formatPath(MainDir.getAbsolutePath() + "\\History"));
            HistoryDir.mkdirs();
            TasksDir = new File(fileTools.formatPath(MainDir.getAbsolutePath() + "\\Tasks"));
            TasksDir.mkdirs();

            // Files
            TasksFile = new File(fileTools.formatPath(MainDir.getAbsolutePath() + "\\Tasks.dat"));
            TasksFile.createNewFile();
            SettingsFile = new File(fileTools.formatPath(MainDir.getAbsolutePath() + "\\Settings.dat"));
            SettingsFile.createNewFile();
        } catch (IOException ex) {
            System.out.println("Could not create the necessary files");
        }
    }
    
    public Settings loadSettings() {
        Settings settings = new Settings();
        ObjectInputStream ois = null;
        try {
            //open streams
            FileInputStream fis = new FileInputStream(SettingsFile);
            BufferedInputStream bis = new BufferedInputStream(fis);
            ois = new ObjectInputStream(bis);

            //load data
            try {
                ArrayList<String> name = (ArrayList<String>) ois.readObject();
                ArrayList value = (ArrayList) ois.readObject();
                settings.loadSettings(name, value);
            } catch (ClassNotFoundException ex) {
                System.out.println("Could not load custom settings, resetting to default");
                settings.reset_settings();
                saveSettings(settings);
                //Logger.getLogger(AppDataManager.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (IOException ex) {
            System.out.println("Could not load custom settings, default one will be used");
            settings.reset_settings();
            saveSettings(settings);
            //Logger.getLogger(AppDataManager.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
            } catch (IOException ex) {
                Logger.getLogger(AppDataManager.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        //create download dirs
        new File(settings.getHttpDestination()).mkdirs();
        
        return settings;
    }
    
    public void saveSettings(Settings settings) {
        ObjectOutputStream oos = null;
        try {
            //open streams
            FileOutputStream fos = new FileOutputStream(SettingsFile);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            oos = new ObjectOutputStream(bos);

            //write data
            oos.writeObject(settings.getNames());
            oos.writeObject(settings.getValues());

            //flush the buffer
            oos.flush();
        } catch (IOException ex) {
            System.out.println("File not found");
            Logger.getLogger(AppDataManager.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                oos.close();
            } catch (IOException ex) {
                Logger.getLogger(AppDataManager.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    
    public void saveHTTPTask(String filename, Object[] data) {
        File f_new = new File(TasksDir.getAbsolutePath() + "\\" + filename + ".dat");
        File f_old = new File(TasksDir.getAbsolutePath() + "\\" + filename + ".bak");

        //switch new/backup
        if (f_new.exists()) {
            if (f_old.exists()) {
                f_old.delete();
            }
            f_new.renameTo(f_old);
        }
        
        ObjectOutputStream oos = null;
        try {
            //open streams
            FileOutputStream fos = new FileOutputStream(f_new);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            oos = new ObjectOutputStream(bos);

            //write data
            //oos.writeObject(data[0]);
            //oos.writeObject(data[1]);
            for (int i = 0; i < data.length; i++) {
                oos.writeObject(data[i]);
            }

            //flush the buffer
            oos.flush();
        } catch (IOException ex) {
            System.out.println("File not found");
            Logger.getLogger(AppDataManager.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                oos.close();
            } catch (IOException ex) {
                Logger.getLogger(AppDataManager.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
    }
    
    public void removeTask(String filename){
        File f = new File(TasksDir.getAbsolutePath() + "\\" + filename + ".dat");
        f.delete();
        f = new File(TasksDir.getAbsolutePath() + "\\" + filename + ".bak");
        f.delete();
    }
    
    public void loadAllTasks() {
        FilenameFilter filter = new SuffixFileFilter(".dat");
        File[] files = TasksDir.listFiles(filter);
        for (int i = 0; i < files.length; i++) {
            loadHTTPTask(files[i]);
        }
    }
    
    public void loadHTTPTask(String filename) {
        File f = new File(TasksDir.getAbsolutePath() + "\\" + filename + ".dat");
        loadHTTPTask(f);
    }
    
    public void loadHTTPTask(File f) {
        HTTPTaskManager task = null;
        
        if (f.exists()) {
            ObjectInputStream ois = null;
            try {
                //open streams
                FileInputStream fis = new FileInputStream(f);
                BufferedInputStream bis = new BufferedInputStream(fis);
                ois = new ObjectInputStream(bis);

                //load data
                try {
                    ArrayList<String> name = (ArrayList<String>) ois.readObject();
                    ArrayList<String> value = (ArrayList) ois.readObject();
                    Object[] RangeProgress = (Object[]) ois.readObject();
                    
                    for (int i = 0; i < name.size(); i++) {
                        System.out.println(name.get(i) + " : " + value.get(i));
                    }
                    
                    task = new HTTPTaskManager(Integer.parseInt(value.get(name.indexOf("NumWorkers"))),
                            Integer.parseInt(value.get(name.indexOf("MaxBufferSize"))),
                            new File(value.get(name.indexOf("FileDestination"))));
                    task.setSourceURL(new URL(value.get(name.indexOf("URL"))));
                    task.resume(Long.parseLong(value.get(name.indexOf("TimeCreated"))),
                            Long.parseLong(value.get(name.indexOf("TimeCompleted"))),
                            Long.parseLong(value.get(name.indexOf("TimeWorking"))),
                            value.get(name.indexOf("TaskName")),
                            Status.valueOf(value.get(name.indexOf("TaskStatus"))),
                            Long.parseLong(value.get(name.indexOf("ContentLength"))),
                            RangeProgress);
                    tableTaskManager.addHttpTask(task);
                    task.addOutputGUI(mainWindow);
                    
                } catch (ClassNotFoundException ex) {
                    System.out.println("Task could not be loaded");
                    //Logger.getLogger(AppDataManager.class.getName()).log(Level.SEVERE, null, ex);
                }
            } catch (IOException ex) {
                System.out.println("Task could not be loaded");
                //Logger.getLogger(AppDataManager.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                try {
                    ois.close();
                } catch (IOException ex) {
                    Logger.getLogger(AppDataManager.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } else {
            System.out.println("Task does not exist anymore!");
        }
    }
}
